To make good looking Vue apps, we need to style our components. To make our lives easier, we can use components with styles built-in. Today we’ll look at how to customize table contents, including headers and footers.
Rendering Custom Headers and Footers
We can customize the render of headers and footers by populating slots.
For example, we can write:
<template>
<div id="app">
<b-table :items="items" foot-clone>
<template v-slot:head(firstName)="data">
<span>{{ data.label.toUpperCase() }}</span>
</template>
<template v-slot:foot()="data">
<span>{{ data.label.toUpperCase() }}</span>
</template>
</b-table>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
items: [
{ firstName: "alex", lastName: "green" },
{
firstName: "may",
lastName: "smith"
},
{ firstName: "james", lastName: "jones" }
]
};
}
};
</script>
With the head
slot, we can format the header. We can pass in the field name for the field we want to format. Or we can leave it blank to format all column headers. Likewise, we can do the same for footer.
Add Additional Rows top the Header
We can add more rows to the header.
To do that, we populate the thead-top
slot.
Inside the slot, we use the b-tr
component to add a table row.
Then inside it, we add our b-th
components to add the headers.
For example, we can write:
<template>
<div id="app">
<b-table :items="items">
<template v-slot:thead-top="data">
<b-tr>
<b-th>
<span>Name</span>
</b-th>
<b-th>Surname</b-th>
</b-tr>
</template>
</b-table>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
items: [
{ firstName: "alex", lastName: "green" },
{
firstName: "may",
lastName: "smith"
},
{ firstName: "james", lastName: "jones" }
]
};
}
};
</script>
Now we have the table header with the cells Name and Surname on top of the table.
Custom Footer
We can create a custom footer. To add a custom footer, we can populate the custom-foot
slot.
We can write:
<template>
<div id="app">
<b-table :items="items">
<template v-slot:custom-foot="data">
<b-tr>
<b-td>Name</b-td>
<b-td>Surname</b-td>
</b-tr>
</template>
</b-table>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
items: [
{ firstName: "alex", lastName: "green" },
{
firstName: "may",
lastName: "smith"
},
{ firstName: "james", lastName: "jones" }
]
};
}
};
</script>
We populate the custom-foot
slot with the b-tr
and b-td
components to make our own footer row. It won’t be rendered if we have the foot-clone
prop set.
Custom Empty Table Rendering
We can render something of our choice if we have an empty table. To customize the content, we can populate the empty
and emptyfiltered
slot.
For example, we can write:
<template>
<div id="app">
<b-table :items="items" show-empty>
<template v-slot:empty="scope">
<h4>{{ scope.emptyText }}</h4>
</template>
<template v-slot:emptyfiltered="scope">
<h4>{{ scope.emptyFilteredText }}</h4>
</template>
</b-table>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
items: []
};
}
};
</script>
Then we see ‘There are no records to show’ since there’s no data in items
.
We can customize the text with some props:
`<template>
<div id="app">
<b-table :items="items" show-empty empty-text="nothing to see">
<template v-slot:empty="scope">
<h4>{{ scope.emptyText }}</h4>
</template>
<template v-slot:emptyfiltered="scope">
<h4>{{ scope.emptyFilteredText }}</h4>
</template>
</b-table>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
items: []
};
}
};
</script>
We set the empty-text
prop to 'nothing to see'
, so that’s the value of scope.emptyText
and it’s displayed.
There’s also the empty-html
prop to set the HTML content for empty text.
The value will be available in scope.emptyHtml
.
emptyFilterHtml
is set by the empty-filtered-html
.
emptyFilteredText
is set by the empty-filtered-text
.
Sticky Headers
We can make the header sticky with the sticky-header
prop. The value can be set to the maximum height of the table in pixels.
For example, we can write:
<template>
<div id="app">
<b-table :items="items" sticky-header head-variant="light"></b-table>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
items: [
{ firstName: "alex", lastName: "green" },
{
firstName: "may",
lastName: "smith"
},
{ firstName: "james", lastName: "jones" },
{ firstName: "james", lastName: "jones" },
{ firstName: "james", lastName: "jones" },
{ firstName: "james", lastName: "jones" },
{ firstName: "james", lastName: "jones" },
{ firstName: "james", lastName: "jones" }
]
};
}
};
</script>
Then the header will always stay on the top.
Conclusion
We can make headers sticky. Also, we can customize the layout of the header and footer.